﻿using System;
using System.Reflection;
using System.Windows.Forms;

namespace Sys.Controls.Dialogs
{
    public partial class AssemblyBrowserDialog : Form
    {
        public DialogResult Result { get; private set; }

        public Assembly Assembly { get; private set; }

        public Type Type { get; private set; }

        public AssemblyBrowserDialog()
        {
            InitializeComponent();

            
        }

        private void BrowseAssembly()
        {
            OpenFileDialog d = new OpenFileDialog();
            d.AddExtension = true;
            d.AutoUpgradeEnabled = true;
            d.CheckFileExists = true;
            d.CheckPathExists = true;
            d.Multiselect = false;
            d.ReadOnlyChecked = true;
            d.RestoreDirectory = true;
            d.Title = "Select an assembly";
            d.Filter = "Libraries|*.dll|Executables|*.exe";

            if (d.ShowDialog() == DialogResult.OK)
            {
                Invalidate();

                Assembly = Assembly.LoadFile(d.FileName);

                Text = string.Format("Select a types in {0}", Assembly.FullName);
            }
        }

        public new void Show()
        {
            BrowseAssembly();
            
            cboCategory.SelectedIndex = 0;

            Invalidate();
            
            base.Show();
        }

        private void OnOkay(object sender, EventArgs e)
        {
            Type = txtType.Tag as Type;

            Result = DialogResult.OK;

            Close();
        }

        private void OnCancel(object sender, EventArgs e)
        {
            Result = DialogResult.Cancel;
            Assembly = null;
            Type = null;

            Close();
        }

        private void OnCategoryChanged(object sender, EventArgs e)
        {
            lvTypes.Items.Clear();

            if (cboCategory.Text.Equals("All Categories"))
            {
                foreach (Type t in Assembly.GetTypes())
                {
                    if (t.IsClass)
                    {
                        ListViewItem l = new ListViewItem(new string[] { t.Name, t.FullName });
                        l.Tag = t;

                        lvTypes.Items.Add(l);
                    }

                    if (t.IsInterface)
                    {
                        ListViewItem l = new ListViewItem(new string[] { t.Name, t.FullName });
                        l.Tag = t;

                        lvTypes.Items.Add(l);
                    }
                }
            }

            if (cboCategory.Text.Equals("Classes"))
            {
                foreach (Type t in Assembly.GetTypes())
                {
                    if (t.IsClass)
                    {
                        ListViewItem l = new ListViewItem(new string[] { t.Name, t.FullName });
                        l.Tag = t;

                        lvTypes.Items.Add(l);
                    }
                }
            }

            if (cboCategory.Text.Equals("Interfaces"))
            {
                foreach (Type t in Assembly.GetTypes())
                {
                    if (t.IsInterface)
                    {
                        ListViewItem l = new ListViewItem(new string[] { t.Name, t.FullName });
                        l.Tag = t;

                        lvTypes.Items.Add(l);
                    }
                }
            }
        }

        private void OnTypeChanged(object sender, EventArgs e)
        {
            if (lvTypes.SelectedItems != null)
            {
                foreach (ListViewItem item in lvTypes.SelectedItems)
                {
                    txtType.Tag = item.Tag;
                    txtType.Text = (item.Tag as Type).AssemblyQualifiedName;
                }
            }
        }
    }
}
